package optimizers.ganeat.oscillator.robustfaststrong;

import java.util.Map;

import model.OligoSystemGeneral;

import fitness.Fitness;
import fitness.RobustFastStrongOscillatorFitness;
import fitness.RobustFastStrongOscillatorResult;

import optimizers.commons.RunConfig;
import optimizers.ganeat.GA;
import optimizers.ganeat.Individual;
import optimizers.ganeat.Node;
import optimizers.ganeat.Constants;
import optimizers.ganeat.sin.GASin;
import optimizers.ganeat.sin.IndividualSin;
import runconfiguration.RobustFSOConfiguration;
import runconfiguration.SinConfiguration;
import visualization.GraphDisplayer;

public class GARobustFSO extends GA {

	/*
	 * @Override public Individual getInitialIndividual() { IndividualFSO indiv
	 * = new IndividualFSO(innovations, nodeNames, -1, 0);
	 * indiv.nodeGenes.add(new Node("a", 89.92, Node.SIMPLE_SEQUENCE));
	 * indiv.nodeGenes.add(new Node("b", 70, Node.SIMPLE_SEQUENCE));
	 * indiv.nodeGenes.add(new Node("Iaa", Constants.defaultNodeParam,
	 * Node.INHIBITING_SEQUENCE)); indiv.nodeGenes.add(new Node("Ibb",
	 * Constants.defaultNodeParam, Node.INHIBITING_SEQUENCE));
	 * indiv.addConnection(indiv.getNode("a"), indiv.getNode("Iaa"), true, 30);
	 * indiv.addConnection(indiv.getNode("a"), indiv.getNode("a"), true, 5);
	 * indiv.addConnection(indiv.getNode("b"), indiv.getNode("b"), true, 5);
	 * indiv.addConnection(indiv.getNode("b"), indiv.getNode("Ibb"), true, 10);
	 * return indiv; }
	 */

	public GARobustFSO(RunConfig config) {
		super(config);
		this.maxRunTime = 150;
	}

	/*
	 * @Override public Individual getInitialIndividual() { IndividualFSO indiv
	 * = new IndividualFSO(innovations, nodeNames, -1, 0);
	 * indiv.nodeGenes.add(new Node("a", 50, Node.SIMPLE_SEQUENCE));
	 * indiv.nodeGenes.add(new Node("b", 50, Node.SIMPLE_SEQUENCE));
	 * indiv.nodeGenes.add(new Node("c", 50, Node.SIMPLE_SEQUENCE));
	 * indiv.nodeGenes.add(new Node("d", 50, Node.SIMPLE_SEQUENCE));
	 * indiv.nodeGenes.add(new Node("e", 50, Node.SIMPLE_SEQUENCE));
	 * 
	 * indiv.addConnection(indiv.getNode("a"), indiv.getNode("a"), true, 21);
	 * indiv.addConnection(indiv.getNode("b"), indiv.getNode("b"), true, 20);
	 * indiv.addConnection(indiv.getNode("c"), indiv.getNode("c"), true, 20);
	 * indiv.addConnection(indiv.getNode("d"), indiv.getNode("d"), true, 20);
	 * indiv.addConnection(indiv.getNode("e"), indiv.getNode("e"), true, 20);
	 * indiv.addConnection(indiv.getNode("a"), indiv.getNode("b"), true, 10);
	 * indiv.addConnection(indiv.getNode("b"), indiv.getNode("c"), true, 10);
	 * indiv.addConnection(indiv.getNode("c"), indiv.getNode("d"), true, 10);
	 * indiv.addConnection(indiv.getNode("d"), indiv.getNode("e"), true, 10);
	 * indiv.addConnection(indiv.getNode("e"), indiv.getNode("a"), true, 10);
	 * return indiv; }
	 */
	@Override
	public Individual getInitialIndividual() {
		IndividualRobustFSO indiv = new IndividualRobustFSO(innovations,
				nodeNames, -1, 0, config, "Node gens:\r\n" + 
						" a 73.921 9.6335\r\n" + 
						" c 74.1655 1\r\n" + 
						" Icc 0.7417 1\r\n" + 
						" i 116.806 1\r\n" + 
						" r 37.1629 1\r\n" + 
						"Connection gens:\r\n" + 
						" 1 a->a false 4.9\r\n" + 
						" 7 a->c false 0.6804\r\n" + 
						" 8 c->a false 9.3231\r\n" + 
						" 16 c->c true 15.9186\r\n" + 
						" 17 a->Icc true 37.208\r\n" + 
						" 43 c->i false 0.3631\r\n" + 
						" 44 i->a true 60\r\n" + 
						" 87 c->r true 4.2666\r\n" + 
						" 88 r->i true 10.1278\r\n" + 
						"Exo: 0\r\n" + 
						"Pol: 0\r\n" + 
						"Nick: 0");
		return indiv;
	}

	@Override
	public Individual getNewIndividual(Map<String, Integer> innovations2,
			Map<String, String> nodeNames2, int i, int j) {
		return new IndividualRobustFSO(innovations2, nodeNames2, i, j, config);
	}

	@Override
	public String getProblemName() {
		return "RobustFastStrongOscillator";
	}

	@Override
	protected void postEvaluation(Individual[] nextGen) {
		for (int i = 0; i < nextGen.length; i++) {
			RobustFastStrongOscillatorResult fitness = (RobustFastStrongOscillatorResult) nextGen[i].fitnessResult;
			if (fitness.standardModel != fitness.tests[0]) {
				for (Node node : nextGen[i].nodeGenes) {
					if (node.type == Node.SIMPLE_SEQUENCE) {
						OligoSystemGeneral oligoModel = nextGen[i]
								.getOligoModel();
						if (oligoModel.nameToInt.get(node.name) >= fitness.tests[0].seqK[0].length) {
							System.out.println("Something wrong");
						} else {
							node.parameter = Math
									.min(config.seqK.maxValue,
											fitness.tests[0].seqK[0][oligoModel.nameToInt
													.get(node.name)]);
						}
					}
				}
			}
		}
	}

}
